﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Syspetro.Core.Extensions
{
    public static class TypeHelper
    {
        public static bool IsFunc(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            var type = obj.GetType();
            if (!type.GetTypeInfo().IsGenericType)
            {
                return false;
            }

            return type.GetGenericTypeDefinition() == typeof(Func<>);
        }

        public static bool IsFunc<TReturn>(object obj)
        {
            return obj != null && obj.GetType() == typeof(Func<TReturn>);
        }

        public static bool IsPrimitiveExtendedIncludingNullable(Type type, bool includeEnums = false)
        {
            if (IsPrimitiveExtended(type, includeEnums))
            {
                return true;
            }

            if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                return IsPrimitiveExtended(type.GenericTypeArguments[0], includeEnums);
            }

            return false;
        }

        private static bool IsPrimitiveExtended(Type type, bool includeEnums)
        {
            if (type.GetTypeInfo().IsPrimitive)
            {
                return true;
            }

            if (includeEnums && type.GetTypeInfo().IsEnum)
            {
                return true;
            }

            return type == typeof(string) ||
                   type == typeof(decimal) ||
                   type == typeof(DateTime) ||
                   type == typeof(DateTimeOffset) ||
                   type == typeof(TimeSpan) ||
                   type == typeof(Guid);
        }

        /// <summary>
        /// 将字符串转化为指定类型
        /// </summary>
        /// <param name="type">指定的类型</param>
        /// <param name="str">需要转换的字符串</param>
        /// <returns></returns>
        public static object ChangeTo(Type type, string str)
        {
            str = str.Trim();
            if (string.IsNullOrEmpty(str)) return default;
            else if (type == typeof(Guid)) return Guid.Parse(str);
            return Convert.ChangeType(str, type);
        }

        public static double[,] List_Dimension(List<double[]> listData)
        {
            if (listData == null || listData.Count == 0)
                return null;
            double[,] data = new double[listData.Count, listData[0].Length];
            for (int i = 0; i < listData.Count; i++)
            {
                for (int y = 0; y < listData[i].Length; y++)
                {
                    data[i, y] = listData[i][y];
                }
            }
            return data;
        }
        public static List<double[]> Dimension_List(double[,] listData)
        {
            if (listData == null || listData.Length == 0)
                return null;
            int col = listData.GetLength(0);
            List<double[]> data = new();
            for (int i = 0; i < listData.Length/listData.Rank; i++)
            {
                double[] _data = new double[col];
                for (int y = 0; y < col; y++)
                {
                    _data[y] = listData[i, y];
                }
                data.Add(_data);
            }
            return data;
        }
    }
}
